﻿// Copyright 2005, 2006 - Morten Nielsen (www.iter.dk)
//
// This file is part of SharpMap.
// SharpMap is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
// 
// SharpMap is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Lesser General Public License for more details.

// You should have received a copy of the GNU Lesser General Public License
// along with SharpMap; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 

using System;
using System.Collections.Generic;
using System.Text;

namespace Petra.Gis.ReferenceSystemServices
{
  /// <summary>
  /// A coordinate system based on latitude and longitude. 
  /// </summary>
  /// <remarks>
  /// Some geographic coordinate systems are Lat/Lon, and some are Lon/Lat. 
  /// You can find out which this is by examining the axes. You should also 
  /// check the angular units, since not all geographic coordinate systems 
  /// use degrees.
  /// </remarks>
  public class GeographicCoordinateSystem : HorizontalCoordinateSystem
  {


    /// <summary>
    /// xaml constr.
    /// </summary>
    public GeographicCoordinateSystem() { }





    /// <summary>
    /// Creates an instance of a Geographic Coordinate System
    /// </summary>
    /// <param name="horizontalDatum">Horizontal datum</param>
    /// <param name="angularUnit">Angular units</param>
    /// <param name="primeMeridian">Prime meridian</param>
    /// <param name="axes">Axis info</param>
    /// <param name="metadata">Coord. system metadata</param>
    public GeographicCoordinateSystem(HorizontalDatum horizontalDatum, AngularUnit storageUnit, PrimeMeridian primeMeridian, AxisList axes, Metadata metadata)
      :
      base(horizontalDatum, storageUnit, axes, metadata)
    {
      _PrimeMeridian = primeMeridian;
    }

    //#region Predefined geographic coordinate systems

    ///// <summary>
    ///// Creates a decimal degrees geographic coordinate system based on the WGS84 ellipsoid, suitable for GPS measurements
    ///// </summary>
    //public static GeographicCoordinateSystem WGS84
    //{
    //  get
    //  {
    //    List<AxisInfo> axes = new List<AxisInfo>(2);
    //    axes.Add(new AxisInfo("Lon", AxisOrientationEnum.East));
    //    axes.Add(new AxisInfo("Lat", AxisOrientationEnum.North));
    //    return new GeographicCoordinateSystem(SharpMap.CoordinateSystems.AngularUnit.Degrees,
    //      SharpMap.CoordinateSystems.HorizontalDatum.WGS84, SharpMap.CoordinateSystems.PrimeMeridian.Greenwich, axes,
    //      "WGS 84", "EPSG", 4326, String.Empty, string.Empty, string.Empty);
    //  }
    //}

    //#endregion

    #region GeographicCoordinateSystem Members


    /// <summary>
    /// Gets or sets the angular units of the geographic coordinate system.
    /// </summary>
    public override SpatialUnit StorageUnit
    {
      get { return _storageUnits; }
      set { _storageUnits = (AngularUnit)value; }
    }




    private PrimeMeridian _PrimeMeridian;

    /// <summary>
    /// Gets or sets the prime meridian of the geographic coordinate system.
    /// </summary>
    public PrimeMeridian PrimeMeridian
    {
      get { return _PrimeMeridian; }
      set { _PrimeMeridian = value; }
    }




    /// <summary>
    /// Checks whether the values of this instance is equal to the values of another instance.
    /// Only parameters used for coordinate system are used for comparison.
    /// Name, abbreviation, authority, alias and remarks are ignored in the comparison.
    /// </summary>
    /// <param name="obj"></param>
    /// <returns>True if equal</returns>
    public override bool EqualParams(CoordinateSystem obj, bool ignoreStorageUnits)
    {
      if (!(obj is GeographicCoordinateSystem))
        return false;
      GeographicCoordinateSystem gcs = obj as GeographicCoordinateSystem;
      if (gcs.Dimension != this.Dimension) return false;

      if (this.Axes.Count != gcs.Axes.Count) return false;
      for (int i = 0; i < gcs.Axes.Count; i++)
        if (gcs.Axes[i].Orientation != this.Axes[i].Orientation)
          return false;

      if (ignoreStorageUnits)
        return gcs.HorizontalDatum.EqualParams(this.HorizontalDatum) &&
            gcs.PrimeMeridian.EqualParams(this.PrimeMeridian);
      else
        return gcs.StorageUnit.EqualParams(this.StorageUnit) &&
            gcs.HorizontalDatum.EqualParams(this.HorizontalDatum) &&
            gcs.PrimeMeridian.EqualParams(this.PrimeMeridian);

    }
    #endregion
  }
}
